<template>
  <div class="chart-container">
    <v-chart
      ref="chartRef"
      :option="chartOption"
      :update-options="{ notMerge: false }"
      autoresize
    />
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted } from 'vue'
import * as echarts from 'echarts/core'
import { LineChart } from 'echarts/charts'
import {
  TitleComponent,
  TooltipComponent,
  GridComponent,
  DataZoomComponent
} from 'echarts/components'
import { CanvasRenderer } from 'echarts/renderers'
import VChart from 'vue-echarts'

// 注册ECharts组件
echarts.use([
  TitleComponent,
  TooltipComponent,
  GridComponent,
  DataZoomComponent,
  LineChart,
  CanvasRenderer
])

// 定义动画常量
const ANIMATION_DURATION = 3000
const ANIMATION_STEP = 50

// 定义响应式数据
const chartOption = ref({})
const chartRef = ref(null)

/**
 * 获取年度电影数量数据
 * @returns {Promise<Object>} 包含年度电影数量数据的Promise
 */
async function fetchMovieCountByYear() {
  try {
    const response = await fetch('/api/queryMovieCountByYear')
    const list = await response.json()

    // 验证返回数据格式
    if (!Array.isArray(list)) {
      throw new Error('后端返回的数据格式不正确')
    }

    // 按年份排序
    list.sort((a, b) => a.year - b.year)

    // 转换数据格式
    const seriesData = list.map(item => [
      String(item.year),
      item.movieCount
    ])

    return { seriesData }
  } catch (error) {
    console.error('获取电影数量数据失败:', error)
    throw error
  }
}

/**
 * 构建图表配置选项
 */
async function makeOption() {
  try {
    const data = await fetchMovieCountByYear()
    const xData = data.seriesData.map(item => item[0])

    chartOption.value = {
      title: {
        text: '各年份电影发行数量统计',
        left: 'center'
      },
      tooltip: {
        show: true,
        trigger: 'axis'
      },
      xAxis: {
        type: 'category',
        data: xData,
        boundaryGap: false,
        axisLabel: {
          formatter: '{value}'
        }
      },
      yAxis: {
        type: 'value',
        min: 0
      },
      dataZoom: [
        {
          type: 'inside',
          xAxisIndex: 0
        },
        {
          type: 'slider',
          xAxisIndex: 0,
          showDetail: false,
          handleStyle: {
            showLabel: false
          },
          formatter: () => ''
        }
      ],
      series: [
        {
          type: 'line',
          symbolSize: 0,
          name: '电影数量',
          data: [], // 初始为空数据
          labelLayout: {
            moveOverlap: 'shiftY'
          },
          emphasis: {
            focus: 'series'
          },
          encode: {
            x: 0,
            y: 1
          }
        }
      ]
    }
  } catch (error) {
    console.error('构建图表配置失败:', error)
  }
}

/**
 * 组件挂载后执行
 */
onMounted(async () => {
  // 初始化图表配置
  await makeOption()

  try {
    // 获取完整数据
    const fullData = await fetchMovieCountByYear()
    const full = fullData.seriesData
    const total = full.length
    let frame = 0

    // 设置动画定时器
    const timer = setInterval(() => {
      // 计算当前帧应显示的数据
      const show = full.slice(0, Math.round((frame + 1) * total / (ANIMATION_DURATION / ANIMATION_STEP)))

      // 安全地更新图表数据
      if (chartRef.value) {
        chartRef.value.setOption({
          series: [{
            data: show
          }]
        })
      }

      // 动画结束时清理定时器
      if (++frame >= ANIMATION_DURATION / ANIMATION_STEP) {
        clearInterval(timer)
      }
    }, ANIMATION_STEP)
  } catch (error) {
    console.error('执行动画时出错:', error)
  }
})

/**
 * 组件卸载前执行
 */
onUnmounted(() => {
  // 安全地销毁图表实例
  if (chartRef.value) {
    chartRef.value.dispose()
  }
})
</script>

<style scoped>
.chart-container {
  margin-top: -8vh;
  margin-left: -4vw;
  width: 93vw;
  height: 600px;
}
</style>
